package com.tsystems.train.service;

import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Stateless;

import com.tsystems.train.dao.StationDAO;
import com.tsystems.train.dao.TrainDAO;
import com.tsystems.train.dao.UserDAO;
import com.tsystems.train.dao.TicketDAO;
import com.tsystems.train.dao.TimeTableElementDAO;
import com.tsystems.train.entity.User;
import com.tsystems.train.entity.Station;
import com.tsystems.train.entity.Ticket;
import com.tsystems.train.entity.TimeTableElement;
import com.tsystems.train.entity.Train;

/**
 * 
 * @author Turybrin Vladislav
 * 
 *         The class contains methods for performing basic operations with
 *         stations.
 */
@Stateless
public class TicketServices {

	@EJB
	private UserDAO passengerDAO;

	@EJB
	private TicketDAO ticketDAO;

	@EJB
	private StationDAO stationDAO;

	@EJB
	private TrainDAO trainDAO;

	@EJB
	private TimeTableElementDAO tteDAO;

	@EJB
	private TimeTableElementServices tteS;

	/**
	 * Gets a list of the current user tickets
	 * 
	 * @param login
	 *            -cuurent user login
	 * @return list of the current user tickets 
	 */
	public List<Ticket> viewTickets(String login) {
		User passenger = passengerDAO.getPassenger(login);

		if (passenger == null) {
			return Collections.emptyList();
		}

		List<Ticket> result = ticketDAO.getTicketsByPassenger(passenger);
		return result;
	}

	/**
	 * The method of performing the operation of ticket purchase by the current user
	 * 
	 * @param fromStation
	 *            - departure station
	 * @param toStation
	 *            - arrival station
	 * @param fromTime
	 *            - departure time
	 * @param train
	 *            
	 * @param arrivalTime
	 *            - arrival time
	 * @param login
	 *            - current user login.
	 * @return "Buying a ticket is successfully completed", if it so
	 *         otherwise - message with error information
	 */
	@Lock(LockType.WRITE)
	public String buyTicket(Station fromStation, Station toStation,
			Date fromTime, Train train, Date arrivalTime, String login) {

		fromStation = stationDAO.getStationByName(fromStation.getName());
		toStation = stationDAO.getStationByName(toStation.getName());
		train = trainDAO.getTrainByNumber(train.getNumber());

		Date currentTime = Calendar.getInstance().getTime();
		if ((login == null)
				|| fromTime.getTime() - currentTime.getTime() < 600000) {
			return "It is impossible to buy a ticket. Up to the time of departure has less than 10 minutes.";
		}

		User passengerFound = passengerDAO.getPassenger(login);

		if (passengerFound == null) {
			return "You can not buy a ticket. User is not in the database. ";
		}

		TimeTableElement departureTTE = tteDAO
				.getTimeTableElementByDepartureInformation(train, fromStation,
						fromTime);

		List<TimeTableElement> arrivalList = tteDAO
				.getTimeTableElementByArrivalInformation(train, toStation,
						arrivalTime);
		List<TimeTableElement> path = null;
		for (TimeTableElement element : arrivalList) {
			path = tteS.mergePath(departureTTE, element);
			if (!path.isEmpty()) {
				break;
			}

		}
		if (path == null || path.isEmpty()) {
			return "There are no trains passing from" + fromStation + " to "
					+ toStation + " at thi time";
		}

		for (TimeTableElement element : path) {
			if (ticketDAO.getTicketsByPassengerAndTTE(passengerFound, element) != null) {
				return "Tickets are already registered on the current user!";
			}
			if (ticketDAO.getTickestByTTE(element).size() >= train.getSeats()) {
				return "Tickets for this train are over.";
			}

			ticketDAO.insert(new Ticket(passengerFound, element));
		}

		return "Buying a ticket is successfully completed";
	}

}
